/**
  ******************************************************************************
  * @file    main.c
  * @author  MCD Application Team
  * @version V1.2.1
  * @date    30-September-2014
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm8l10x.h"
#include "main.h"
/**
  * @addtogroup FLASH_ByteReadWriteOperation
  * @{
  */

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
typedef enum { FAILED = 0, PASSED = !FAILED} TestStatus;
__IO TestStatus OperationStatus = FAILED;

uint16_t CCR1_Val;
uint16_t hTimer1mS, hIdle_Time;

uint8_t duty;

State_t Work_State;
/* Private function prototypes -----------------------------------------------*/
static void TIM2_Config(void);
static void TIM3_Config(void);


uint8_t Flash_RW_Value( uint8_t val_new);
//static void Sleep_Config(void);

void Delay(uint16_t nCount);
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program.
  *  default Clock HSI/8 ==2MHz
  * @param  None
  * @retval None
  */
void main(void)
{
  uint16_t add = 0;

  Work_State = State_Idle;

  /*set cpu clock 4MHz */
  CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv4);
  GPIO_Config();
  TIM2_Config();
  TIM3_Config();
  
  /*get duty value from eeprom*/
  add = 0x9800;
  duty = FLASH_ReadByte(add);
  if( duty == 0x00)
    duty = Flash_RW_Value(0x05);
  
  Gpio_set_enc_val(duty);
  /*Power on all LEDs*/
  Gpio_LED_Ctrl(10u);
//  enableInterrupts();
  while(1)
  {
    /*1KHz period task handle */
    if( TIM3->SR1 & TIM3_FLAG_Update )
    {
      hTimer1mS++;
      /*detect key value */
      Proc_GPIO_Status();
      
      switch (Work_State)
      {
      case State_Idle:
        hIdle_Time ++;
        if(hIdle_Time > IDLE_TIME )
        {
          Work_State = State_Run;
          duty = Gpio_get_enc_val();
          TIM2_SetCompare1(duty*20u);
          Gpio_LED_Ctrl(duty);
          hIdle_Time = 0u;
        }
        break;
      case State_Run:
        /*update duty if encoder adjusted */
        if(duty != Gpio_get_enc_val() )
        {
          duty = Gpio_get_enc_val();
          TIM2_SetCompare1(duty*20u);
          Gpio_LED_Ctrl(duty);
          hIdle_Time = 0;
        }
        /*get inject key status*/
        if(Gpio_get_key2_val() == 1)
        {
          PWM_OUTPUT_EN();
          hIdle_Time = 0;
        }
        else /*key release */
        {
          PWM_OUTPUT_DIS();
          hIdle_Time++;
        }
        
        /* go to slleep */
        if(hIdle_Time > RUN_TIME)
        {
          /* flash duty data if duty has changed */
          Flash_RW_Value( duty );
          /*disable peripheral */
          hIdle_Time = 0;
          hTimer1mS = 0; 
          Gpio_LED_Ctrl(0u);
          CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv8);

          Work_State = State_Sleep;
        }
        break;
      case State_Sleep:
        
        enableInterrupts();
        halt();
        /* sleeping */

        CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv4);
        GPIO_Config();
        TIM2_Config();
        TIM3_Config();
        
        
        add = 0x9800;
        duty = FLASH_ReadByte(add);

        
        TIM2_SetCompare1(duty*20u);
        Gpio_set_enc_val(duty);
        Gpio_LED_Ctrl(duty);
        // while(1);
        hTimer1mS = 0;
        hIdle_Time = 0;
        Work_State = State_Run;
        break;
      default:
        break;
      }

      TIM3->SR1 = 0x00u;
      GPIO_ToggleBits(GPIOC, GPIO_Pin_0 );
    }
    
    /* Check program action */
    
  }
 
}

uint8_t Flash_RW_Value( uint8_t val_new)
{
  /* Read a byte at a specified address */
  uint16_t add_temp;
  uint8_t temp;
  add_temp = 0x9800;
  temp = FLASH_ReadByte(add_temp);

  if( temp != val_new)
  {
    
    /* Define flash programming Time*/
    FLASH_SetProgrammingTime(FLASH_ProgramTime_Standard);

    FLASH_Unlock(FLASH_MemType_Program);
    /* Wait until Flash Program area unlocked flag is set*/
    while (FLASH_GetFlagStatus(FLASH_FLAG_PUL) == RESET)
    {}

    /* Unlock flash data eeprom memory */
    FLASH_Unlock(FLASH_MemType_Data);
    /* Wait until Data EEPROM area unlocked flag is set*/
    while (FLASH_GetFlagStatus(FLASH_FLAG_DUL) == RESET)
    {}
    FLASH_ProgramByte(add_temp, val_new);
    Delay(300);
    FLASH_Lock(FLASH_MemType_Data);
  }
  return  FLASH_ReadByte(add_temp);
}
/**
  * @brief  Configure TIM2 peripheral
  * @param  None
  * @retval None
  */
static void TIM2_Config(void)
{
  /* Enable TIM2 clock */
  CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE);
  
  /* Config TIM2 Channel 1 and channel 2 pins */
  GPIO_Init(GPIOB, GPIO_Pin_0 , GPIO_Mode_Out_PP_Low_Fast);

  /* Time base configuration  10KHz */
  TIM2_TimeBaseInit(TIM2_Prescaler_1, TIM2_CounterMode_Up, 200-1);

  /* PWM1 Mode configuration: Channel1 */ 
  TIM2_OC1Init(TIM2_OCMode_PWM1, TIM2_OutputState_Enable, CCR1_Val, TIM2_OCPolarity_High, TIM2_OCIdleState_Set);
  TIM2_OC1PreloadConfig(ENABLE);

  TIM2_ARRPreloadConfig(ENABLE);

  /* Enable TIM2 outputs */
  TIM2_CtrlPWMOutputs(ENABLE);
  
  /* TIM2 enable counter */
  TIM2_Cmd(ENABLE);
}

/**
  * @brief  Configure TIM3 peripheral for timebase 
  * @param  None
  * @retval None
  */
static void TIM3_Config(void)
{
  /* Enable TIM3 clock */
  CLK_PeripheralClockConfig(CLK_Peripheral_TIM3, ENABLE);
  /* Time base configuration  1KHz*/
  TIM3_TimeBaseInit(TIM3_Prescaler_1, TIM3_CounterMode_Up, 2000);
  /* TIM3 enable counter */
  TIM3_Cmd(ENABLE);
}

/**
  * @brief  Delay.
  * @param  nCount
  * @retval None
  */
void Delay(uint16_t nCount)
{
    /* Decrement nCount value */
    while (nCount != 0)
    {
        nCount--;
    }
}


#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval : None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
